package com.jingbian.cppccbackend.service.impl.admin;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jingbian.cppccbackend.entity.Meetings;
import com.jingbian.cppccbackend.entity.Users;
import com.jingbian.cppccbackend.entity.dto.AddMeetingDTO;
import com.jingbian.cppccbackend.entity.dto.UpdateMeetingDTO;
import com.jingbian.cppccbackend.mapper.admin.adminMeetingsMapper;
import com.jingbian.cppccbackend.service.admin.MeetingsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jingbian.cppccbackend.entity.vo.MeetingDetailVO;
import com.jingbian.cppccbackend.entity.vo.PageVO;
import com.jingbian.cppccbackend.entity.MeetingAttachments;
import com.jingbian.cppccbackend.entity.MeetingParticipants;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import java.util.List;
import java.util.Map;
import java.util.HashMap;

/**
 * <p>
 * 会议表，用于存储会议基本信息 服务实现类
 * </p>
 *
 * @author yezi
 * @since 2025-02-26
 */
@Service
public class adminMeetingsServiceImpl extends ServiceImpl<adminMeetingsMapper, Meetings> implements MeetingsService {

    @Autowired
    adminMeetingsMapper adminMeetingsMapper;
    @Override
    public PageVO<Meetings> getMeetings(Integer pageNum, Integer pageSize, String sortType, String startDate, String endDate, String searchText, String status, Boolean isMeeting) {
        PageVO<Meetings> pb = new PageVO<>();
        PageHelper.startPage(pageNum, pageSize);
        List<Meetings> meetings = adminMeetingsMapper.getMeetings(sortType, startDate, endDate, searchText, status, isMeeting);
        Page<Meetings> pag = (Page<Meetings>) meetings;
        pb.setTotal(pag.getTotal());
        pb.setItems(pag.getResult());
        return pb;
    }

    @Override
    public PageVO<Meetings> getEndedMeetings(Integer pageNum, Integer pageSize, String sortType, String startDate, String endDate, String searchText, String status, Boolean isMeeting) {
        PageVO<Meetings> pb = new PageVO<>();
        PageHelper.startPage(pageNum, pageSize);
        List<Meetings> meetings = adminMeetingsMapper.getEndedMeetings(sortType, startDate, endDate, searchText, status, isMeeting);
        Page<Meetings> pag = (Page<Meetings>) meetings;
        pb.setTotal(pag.getTotal());
        pb.setItems(pag.getResult());
        return pb;
    }

    @Override
    public List<Meetings> getMeetingsList(String sortType, String startDate, String endDate, String searchText, String status, Boolean isMeeting) {
        return adminMeetingsMapper.getEndedMeetings(sortType, startDate, endDate, searchText, status, isMeeting);
    }

    @Override
    public MeetingDetailVO getMeetingDetail(Integer mid) {
        MeetingDetailVO detailVO = new MeetingDetailVO();
        
        // 1. 获取会议基本信息
        Meetings meetingInfo = adminMeetingsMapper.getMeetingById(mid);
        if (meetingInfo == null) {
            return null;
        }
        detailVO.setMeetingInfo(meetingInfo);
        
        // 2. 获取参会人详细信息
        List<MeetingDetailVO.ParticipantInfo> participants = adminMeetingsMapper.getMeetingParticipants(mid);
        detailVO.setParticipants(participants);

        // 3. 获取会议附件信息
        List<MeetingDetailVO.AttachmentInfo> attachments = adminMeetingsMapper.getMeetingAttachments(mid);
        detailVO.setAttachments(attachments);

        // 4. 设置统计信息
        int totalParticipants = participants != null ? participants.size() : 0;
        long signedCount = participants != null ? 
            participants.stream().filter(p -> "已签到".equals(p.getStatus())).count() : 0;
        
        detailVO.setTotalParticipants(totalParticipants);
        detailVO.setSignedCount((int) signedCount);
        detailVO.setUnsignedCount(totalParticipants - (int) signedCount);
        
        return detailVO;
    }

    @Override
    public List<Users> getParticipants(String identity, String region, String affiliation, String searchText) {
        List<Users> users = adminMeetingsMapper.getParticipants(identity,region,affiliation,searchText);
        return users;
    }

    @Transactional
    @Override
    public boolean addMeeting(AddMeetingDTO meetingDTO) {
        try {
            // 1. 保存会议/签到基本信息
            Meetings meeting = new Meetings();
            meeting.setTitle(meetingDTO.getTitle());
            meeting.setIntroduction(meetingDTO.getIntroduction());
            meeting.setOrganizer(meetingDTO.getOrganizer());
            meeting.setIsMeeting(meetingDTO.getIsMeeting());  // 设置是否为会议数据


            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
            meeting.setStartTime(LocalDateTime.parse(meetingDTO.getStartTime(), formatter));
            meeting.setEndTime(LocalDateTime.parse(meetingDTO.getEndTime(), formatter));

            meeting.setLocation1(meetingDTO.getLocation1());
            meeting.setLocation2(meetingDTO.getLocation2());
            meeting.setCreatedAt(LocalDateTime.now());
            meeting.setUpdatedAt(LocalDateTime.now());
            
            boolean saved = this.save(meeting);
            if (!saved) {
                throw new RuntimeException("保存基本信息失败");
            }

            // 2. 如果是会议数据，则保存附件
            if (meetingDTO.getIsMeeting() && meetingDTO.getFiles() != null && !meetingDTO.getFiles().isEmpty()) {
                for (AddMeetingDTO.FileInfo fileInfo : meetingDTO.getFiles()) {
                    MeetingAttachments attachment = new MeetingAttachments();
                    attachment.setMeetingId(meeting.getMid());
                    attachment.setFilePath(fileInfo.getUrl());
                    attachment.setUploadTime(LocalDateTime.now());
                    adminMeetingsMapper.insertAttachment(attachment);
                }
            }

            // 3. 保存参与人信息
            if (meetingDTO.getParticipantIds() != null && !meetingDTO.getParticipantIds().isEmpty()) {
                for (Integer userId : meetingDTO.getParticipantIds()) {
                    MeetingParticipants participant = new MeetingParticipants();
                    participant.setMeetingId(meeting.getMid());
                    participant.setUserId(userId);
                    participant.setStatus("未签到");
                    participant.setCreatedAt(LocalDateTime.now());
                    participant.setUpdatedAt(LocalDateTime.now());
                    adminMeetingsMapper.insertParticipant(participant);
                }
            }

            return true;
        } catch (Exception e) {
            log.error("新增失败", e);
            throw new RuntimeException("新增失败: " + e.getMessage());
        }
    }

    @Transactional
    @Override
    public boolean updateMeeting(UpdateMeetingDTO updateDTO) {
        try {
            // 1. 更新基本信息
            Meetings meeting = adminMeetingsMapper.getMeetingById(updateDTO.getMid());
            if (meeting == null) {
                throw new RuntimeException("记录不存在");
            }

            meeting.setTitle(updateDTO.getTitle());
            meeting.setIntroduction(updateDTO.getIntroduction());
            meeting.setOrganizer(updateDTO.getOrganizer());
            meeting.setIsMeeting(updateDTO.getIsMeeting());

            // 修改日期时间处理逻辑
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
            meeting.setStartTime(LocalDateTime.parse(updateDTO.getStartTime(), formatter));
            meeting.setEndTime(LocalDateTime.parse(updateDTO.getEndTime(), formatter));

            meeting.setLocation1(updateDTO.getLocation1());
            meeting.setLocation2(updateDTO.getLocation2());
            meeting.setUpdatedAt(LocalDateTime.now());


            boolean updated = this.updateById(meeting);
            if (!updated) {
                throw new RuntimeException("更新基本信息失败");
            }

            // 2. 如果是会议数据，则处理附件
            if (updateDTO.getIsMeeting()) {
                // 处理要删除的附件
                if (updateDTO.getDeleteFileIds() != null && !updateDTO.getDeleteFileIds().isEmpty()) {
                    for (Integer aid : updateDTO.getDeleteFileIds()) {
                        MeetingAttachments attachment = adminMeetingsMapper.getAttachmentById(aid);
                        if (attachment != null && attachment.getMeetingId().equals(meeting.getMid())) {
                            adminMeetingsMapper.deleteAttachment(aid);
                        }
                    }
                }

                // 添加新的附件
                if (updateDTO.getFiles() != null && !updateDTO.getFiles().isEmpty()) {
                    for (UpdateMeetingDTO.FileInfo fileInfo : updateDTO.getFiles()) {
                        MeetingAttachments attachment = new MeetingAttachments();
                        attachment.setMeetingId(meeting.getMid());
                        attachment.setFilePath(fileInfo.getUrl());
                        attachment.setUploadTime(LocalDateTime.now());
                        adminMeetingsMapper.insertAttachment(attachment);
                    }
                }
            }

            // 3. 更新参与人信息
            adminMeetingsMapper.deleteAllParticipants(meeting.getMid());
            
            if (updateDTO.getParticipantIds() != null && !updateDTO.getParticipantIds().isEmpty()) {
                for (Integer userId : updateDTO.getParticipantIds()) {
                    MeetingParticipants participant = new MeetingParticipants();
                    participant.setMeetingId(meeting.getMid());
                    participant.setUserId(userId);
                    participant.setStatus("未签到");
                    participant.setCreatedAt(LocalDateTime.now());
                    participant.setUpdatedAt(LocalDateTime.now());
                    adminMeetingsMapper.insertParticipant(participant);
                }
            }

            return true;
        } catch (Exception e) {
            log.error("修改失败", e);
            throw new RuntimeException("修改失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getMeetingStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 获取今日会议数量
        Integer todayMeetings = adminMeetingsMapper.getTodayMeetingsCount();
        
        // 获取已结束会议数量
        Integer endedMeetings = adminMeetingsMapper.getEndedMeetingsCount();
        
        // 获取会议总数
        Integer totalMeetings = adminMeetingsMapper.getTotalMeetingsCount();
        
        statistics.put("todayMeetings", todayMeetings);
        statistics.put("endedMeetings", endedMeetings);
        statistics.put("totalMeetings", totalMeetings);
        
        return statistics;
    }
    @Override
    public List<Map<String, Object>> getMeetingTrend(String startDate, String endDate) {
        return adminMeetingsMapper.getMeetingTrend(startDate, endDate);
    }

    @Override
    public byte[] exportTrendData(String startDate, String endDate) throws IOException {
        List<Map<String, Object>> trendData = getMeetingTrend(startDate, endDate);

        try (XSSFWorkbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("会议变化趋势");

            // 设置表头样式
            CellStyle headerStyle = workbook.createCellStyle();
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);

            // 创建表头
            Row headerRow = sheet.createRow(0);
            String[] header = {"日期", "新增会议数量"};

            for (int i = 0; i < header.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(header[i]);
                cell.setCellStyle(headerStyle);
                sheet.autoSizeColumn(i);
            }

            // 填充数据
            int rowNum = 1;
            for (Map<String, Object> data : trendData) {
                Row row = sheet.createRow(rowNum++);
                row.createCell(0).setCellValue(data.get("date").toString());
                row.createCell(1).setCellValue(Integer.parseInt(data.get("value").toString()));
            }

            // 写入字节数组
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            return outputStream.toByteArray();
        }
    }
}
